from . import user_blue
from flask import render_template, g, redirect, url_for, request, jsonify, session
from info.utils.comment import user_login_data
from info import response_code,db, constants
import logging
from info.utils.file_storage import upload_file
from info.models import User, News, Category



@user_blue.route('/info')
@user_login_data
def user_info():
    # 用户中心，用户信息
    user = g.user
    # 如果用户未登录，重定向到index蓝图中index视图函数
    if not user:
        return redirect(url_for('index.index'))

    context = {
        'user': user.to_dict()
    }
    return render_template('news/user.html', context=context)


@user_blue.route('/base_info', methods=['GET', 'POST'])
@user_login_data
def base_info():
    """基本资料
    1 获取用户信息
    2 渲染用户基本界面
    3　修改用户基本资料　接受参数: nick_name  gender  signature
    4 校验参数，参数是否完整，判断gender是否在['MEN','WOMEN']里
    5 更新基本资料，同步到数据库中
    6 修改session['nick_name']的值
    7 返回修改结果

    """


    # 1 获取用户信息
    user = g.user


    # 2 渲染用户基本界面
    if request.method == 'GET':
        context = {
            'user': user.to_dict()
        }
        return render_template('news/user_base_info.html', context=context)

    # 3 修改用户基本资料：
    if request.method == 'POST':
        json_dict = request.json
        nick_name = json_dict.get('nick_name')
        gender = json_dict.get('gender')
        signature = json_dict.get('signature')  # 个性签名

        # 4 校验参数
        if not all([nick_name, gender, signature]):
            return jsonify(errno=response_code.RET.PARAMERR, errmsg='缺少参数')
        if gender not in ['MAN', 'WOMAN']:
            return jsonify(errno=response_code.RET.PARAMERR, errmsg='参数错误')


        # 5 更新基本资料数据
        user.nick_name = nick_name
        user.gender = gender
        user.signature = signature

        try:
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            logging.error(e)
            return jsonify(errno=response_code.RET.DBERR, errmsg='更新用户资料失败')

        #  6 修改session中的nick_name　信息
        session['nick_name'] = nick_name

    # 7  返回响应修改结果
    return jsonify(errno=response_code.RET.OK, errmsg='更新资料成功')


@user_blue.route('/pic_info', methods=['GET', 'POST'])
@user_login_data
def pic_info():
    """用户上传头像
    1 判断用户是否登录，查询用户的基本登录信息
    2 渲染用户头像界面 GET
    3　上传头像  POST

    """

    # 1 查询用户的基本登录信息
    user = g.user

    #　渲染用户头像界面
    if request.method == 'GET':
        context = {
            'user': user.to_dict()
        }
        return render_template('news/user_pic_info.html', context=context)

    # 3　上传头像
    if request.method == 'POST':
        # 接受头像文件
        avatar_file = request.files.get('avatar')
        try:
            # 读取头像图片的二进制信息，
            avatar_data = avatar_file.read()
        except Exception as e:
            logging.error(e)
            return jsonify(errno=response_code.RET.PARAMERR, errmsg='参数错误')

    # 上传
        # 调用七牛云封装的函数方法，将图片的二进制文件上传到七牛云
        try:
            key = upload_file(avatar_data)
        except Exception as e:
            logging.error(e)
            return jsonify(errno=response_code.RET.THIRDERR, errmsg='上传七牛云失败')

        #　将七牛云返回的唯一标识存储到数据库，和user绑定(核心代码)
        user.avatar_url = key
        try:
            db.session.commit()
        except Exception as e:
            logging.error(e)
            return jsonify(errno=response_code.RET.DATAERR, errmsg='保存图片信息失败')

        # 返回上传头像之后的结果
        data = {
            'avatar_url': constants.QINIU_DOMIN_PREFIX + key
        }

        return jsonify(errno=response_code.RET.OK, errmsg='上传图片成功', data=data)


@user_blue.route('/pass_info', methods=['GET', 'POST'])
@user_login_data
def pass_info():
    """修改密码
    1　获取用户登录信息
    2　渲染密码修改界面　　GET
    3　修改密码　　POST
    """
    # 1 获取用户登录信息
    user = g.user
    if not user:
        return redirect(url_for('index.index'))
        # 渲染密码修改页面
    if request.method == 'GET':
        return render_template('news/user_pass_info.html')

    if request.method == 'POST':
        # 接收参数
        old_password = request.json.get('old_password')
        new_password = request.json.get('new_password')

        # 校验参数
        if not all([old_password, new_password]):
            return jsonify(errno=response_code.RET.PARAMERR, errmsg='缺少参数')

        if not user.check_password(old_password):
            return jsonify(errno=response_code.RET.PARAMERR, errmsg='参数错误')


        # 提交到数据库
        user.password = new_password

        try:
            db.session.commit()
        except Exception as e:
            logging.error(e)
            db.session.rollback()
            return jsonify(errno=response_code.RET.DBERR, errmsg='修改密码失败')

        # 响应修改结果
        return jsonify(errno=response_code.RET.OK, errmsg='修改密码成功')


@user_blue.route('/user_collection')
@user_login_data
def user_collection():
    """我的收藏
    1 获取用户的登录信息
    2 查询展示用户的新闻列表　并分页

    """

    # 获取用户的登录信息
    user = g.user
    if not user:
        return redirect(url_for('index.index'))


    page = request.args.get('p', 1)

    # 校验参数，参数是否是整数
    try:
        page = int(page)
    except Exception as e:
        logging.error(e)
        page = 1   # 默认看到的是第一页，不会显示错误信息和崩溃



    # 分页查询
    news_list = []
    current_page = 1
    total_page = 1
    try:
        paginate = user.collection_news.paginate(page, constants.USER_COLLECTION_MAX_NEWS, False)
        #
        news_list = paginate.items
        current_page = paginate.page
        total_page = paginate.pages
    except Exception as e:
        logging.error(e)


    # 构造响应数据
    user_collection_list = []
    for news in news_list:
        user_collection_list.append(news.to_basic_dict())

    context = {
        'news_dict_list': user_collection_list,
        'current_page': current_page,
        'total_page': total_page
    }

    # 返回响应结果
    return render_template('news/user_collection.html', context=context)


@user_blue.route('/news_release', methods=['GET', 'POST'])
@user_login_data
def news_release():
    """新闻发布
    1 获取用户登录信息
    2 渲染新闻发布界面
    3 发布新闻
    """
    user = g.user
    if not user:
        return redirect(url_for('index.index'))

    # 展示新闻发布界面
    if request.method == 'GET':
        categories = None
        # 查询所有的新闻分类信息
        try:
            categories = Category.query.all()
        except Exception as e:
            logging.error(e)

        # 删除新闻的‘最新’分类
        categories.pop(0)
        # 构造响应数据
        context = {
            'categories': categories
        }
        return render_template('news/user_news_release.html', context=context)

    """实现新闻发布逻辑
    1 接受参数 : 新闻标题，新闻分类，新闻副标题，新闻图片，新闻内容，新闻id
    2 校验参数
    3 读取图片二进制信息
    4 上传图片
    5 创建模型
    6 同步到数据库
    7 返回新闻发布结果
    """
    if request.method == 'POST':

        # 接受参数

        title = request.form.get('title')
        category_id = request.form.get('category_id')
        digest = request.form.get('digest')
        index_image = request.files.get('index_image')
        content = request.form.get('content')
        source = '个人发布'

        # 校验参数
        if not all([title, category_id, digest, index_image, content, source]):
            return jsonify(errno=response_code.RET.PARAMERR, errmsg='缺少参数')

        # 读取图片二进制信息
        try:
            index_image_data = index_image.read()
        except Exception as e:
            logging.error(e)
            return jsonify(errno=response_code.RET.DATAERR, errmsg='获取图片信息失败')

        # 上传图片
        try:
            key = upload_file(index_image_data)
        except Exception as e:
            logging.error(e)
            return jsonify(errno=response_code.RET.THIRDERR, errmsg='上传到七牛云失败')

        # 创建模型
        news = News()
        news.title = title
        news.category_id = category_id
        news.digest = digest
        news.index_image_url = constants.QINIU_DOMIN_PREFIX + key
        news.content = content
        news.source = source
        news.user_id = user.id  # 当前发布新闻的user_id
        news.status = 1  # 默认是审核状态

        # 同步到数据库
        try:
            db.session.add(news)
            db.session.commit()
        except Exception as e:
            logging.error(e)
            db.session.rollback()
            return jsonify(errno=response_code.RET.DBERR, errmsg='存储到数据库失败')

        # 返回新闻发布结果
        return jsonify(response_code.RET.OK, errmsg='新闻发布成功')


@user_blue.route('/news_list')
@user_login_data
def user_news_list():
    """我发布的新闻列表"""

    # 获取用户的登录信息
    user = g.user
    if not user:
        return redirect(url_for('index.index'))


    # 获取分页数据
    page = request.args.get('p', 1)

    # 校验参数
    try:
        page = int(page)
    except Exception as e:
        logging.error(e)

    # 分页查询
    paginate = None
    try:
        paginate = News.query.filter(News.user_id == user.id).paginate(page, constants.USER_NEWS_LIST_MAX_COUNT, False)
        news_list = paginate.items
        total_page = paginate.pages
        current_page = paginate.page
    except Exception as e:
        logging.error(e)
        return jsonify(errno=response_code.RET.DATAERR, errmsg='查询数据失败')

    # 构造渲染数据
    news_dict_list = []
    for news in news_list:
        news_dict_list.append(news.to_review_dict())

    context = {
        'news_list': news_dict_list,
        'total_page': total_page,
        'current_page': current_page
    }

    # 响应我发布的新闻列表
    return render_template('news/user_news_list.html', context=context)

@user_blue.route('/user_follow')
@user_login_data
def user_follow():
    """我关注的用户"""

    # 1.获取登录用户信息
    user = g.user
    if not user:
        # 如果用户未登录，重定向到index蓝图中的index视图
        return redirect(url_for('index.index'))

    # 接受参数
    page = request.args.get('p', 1)

    # 校验参数
    try:
        page = int(page)
    except Exception as e:
        logging.error(e)
        page = 1

    # 分页查询
    followed_users = []
    current_page = 1
    total_page = 1
    try:
        paginate = user.followed.paginate(page, constants.USER_FOLLOWED_MAX_COUNT, False)
        # 获取当前页数据
        followed_users = paginate.items
        # 获取当前页
        current_page = paginate.page
        # 获取总页数
        total_page = paginate.pages
    except Exception as e:
        logging.error(e)

    # 4.构造渲染数据
    followed_user_dict_list = []
    for followed_user in followed_users:
        followed_user_dict_list.append(followed_user.to_dict())

    context = {
        "users": followed_user_dict_list,
        "total_page": total_page,
        "current_page": current_page
    }

    # 5.响应结果
    return render_template('news/user_follow.html', context=context)
